/*
 * Integrator.java
 *
 * Created on 11 November 2006, 17:44
 */

package org.foment.gem;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.Statement;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.sql.Time;
import java.util.Calendar;
import java.util.HashSet;
import java.util.logging.Level;
import javax.swing.JInternalFrame;
import javax.swing.JMenuItem;
import javax.swing.LookAndFeel;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import org.foment.data.User;
import org.foment.gem.dialogs.*;
import org.foment.gem.statistic.Employee;
import org.foment.gem.statistic.StatisticsDialog;
import static org.foment.joliage3.core.internationalization.Internationalization.i18n;
import org.foment.joliage3.core.internationalization.Internationalization;

import static org.foment.joliage3.core.logging.Logger.log;
import org.foment.joliage3.core.logging.Logger;
import org.foment.joliage3.core.system.ApplicationInformation;
import org.foment.joliage3.newt.SplashScreen;
import org.foment.joliage3.reports.Report;
import org.foment.joliage3.sql.Database;

/**
 *
 * @author  ivan
 */
public class Integrator extends javax.swing.JFrame implements Internationalization.InitializationListener, Logger.LoggerEventListener, User.UserListener {
  
  public LookAndFeel mainLAF, metalLAF;
  
  private static Integrator _integrator = null;
  
  private java.util.LinkedList <javax.swing.JInternalFrame> _frames = new java.util.LinkedList();
  
  public static Integrator getIntegrator() {
    return _integrator;
  }
  
  private SplashScreen _splash;
  
  public void setActiveEmployee(int employeeID) {
    employeesDialog.setActiveEmployee(employeeID);
  }
  
  /** Creates new form Integrator */
  public Integrator() {
    
    _integrator = this;

    Logger.addLogListener(this);
    Integrator._user.addListener(this);

    _splash = new SplashScreen(new javax.swing.JFrame(), false); // ili false?
    _splash.setMainImage(new javax.swing.ImageIcon(SplashScreen.class.getResource("/org/foment/gem/images/splash.png")));
    _splash.setProgresBarActive(new javax.swing.ImageIcon(SplashScreen.class.getResource("/org/foment/gem/images/splash_progressbar_active.png")));
    _splash.setProgresBarInactive(new javax.swing.ImageIcon(SplashScreen.class.getResource("/org/foment/gem/images/splash_progressbar_inactive.png")));
    _splash.setPadding(2);
    _splash.setBgColor(new java.awt.Color(199, 206, 206));
    _splash.addState("");
    _splash.setVisible(true);
    
    Internationalization.addListener(this);
    Internationalization.initializeTranslations("config.translations.index", "sr");
    
    checkIfRunning();
    
    splash_proceedToNextState();
    
    Database.connect();
    
    splash_proceedToNextState();
    
    Report.initializeReports();
    
    splash_proceedToNextState();

    mainLAF = javax.swing.UIManager.getLookAndFeel();
    metalLAF = new javax.swing.plaf.metal.MetalLookAndFeel();

    initComponents();
    // disable before user has logged in
    //this.setEnabled(false);

    Toolkit kit = getToolkit();
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gs = ge.getScreenDevices();
    Dimension d = kit.getScreenSize();
    setMinimumSize(new java.awt.Dimension(1100, 750));
    setLocation((int) (d.width - getWidth()) / 2, (int) (d.height - getHeight()) / 2);

    LoginDialog ld = new LoginDialog(this, false);
    ld.setLocation(this.getWidth()/2, this.getHeight()/2);


    Integrator._user.setPrivAllAccess(true);
    
    notifications1.addPropertyChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
           
            if (evt.getPropertyName().equals("selectedEmployeeID")) {
                setActiveEmployee(((Integer)evt.getNewValue()).intValue());
            }

        }
    });

    GemInternalDialog.setMainDesktopPane(desktop);

    mnuProgramPositions = new JMenuItem();
    mnuProgramPositions.setText("Poslovi i pozicije");
    mnuProgramPositions.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        mnuProgramPositionsActionPerformed(evt);
      }
    });


    mnuPrintStatistics = new JMenuItem();
    mnuPrintStatistics.setText("Stampanje statistike");
    mnuPrintStatistics.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        mnuPrintStatisticsActionPerformed(evt);
      }
    });

    mnuCourses = new JMenuItem();
    mnuCourses.setText("Uže naučne oblasti / predmeti");
    mnuCourses.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        mnuCoursesActionPerformed(evt);
      }
    });

    mnuProgram.add(mnuProgramPositions);
    mnuProgram.add(mnuCourses);
    mnuProgram.add(mnuPrintStatistics);

    pnlMenu.add(mainMenuBar, java.awt.BorderLayout.CENTER);

    checkPrivileges();
    
    java.awt.GraphicsDevice device;
    device = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    //device.setFullScreenWindow(this);
    
    setExtendedState(MAXIMIZED_BOTH);
    
    ( new Thread() {
      public void run() {
        for (;;) {
          lblDateTime.setText(
            java.text.DateFormat.getDateTimeInstance().format(new java.util.Date())
          );
          try {
            sleep(1000);
          } catch (InterruptedException ex) {
            ex.printStackTrace();
          }
        }
      }
    }).start();
    
    splash_proceedToNextState();
    initDialogs();
    splash_proceedToNextState();

    splash_endState();
  }
  
  private void initDialogs() {
    employeesDialog = new org.foment.gem.dialogs.EmployeesDialog();
    desktop.add(employeesDialog);
    employeesDialog.setVisible(true);
    
    employeesDialog.setSize(desktop.getSize());
     
    try {
      employeesDialog.setMaximum(true);
    } catch (PropertyVetoException ex) {
      ex.printStackTrace();
    }
   
    aboutDialog      = new org.foment.gem.dialogs.AboutDialog();
    printStatsDialog = new org.foment.gem.statistic.StatisticsDialog();
    positionsDialog  = new org.foment.gem.dialogs.PositionsDialog();
    coursesDialog    = new org.foment.gem.dialogs.CoursesDialog();

    mnuPrint.setVisible(false);

    desktop.add(aboutDialog);
    //desktop.add(positionsDialog);

    desktopFrameActivated(employeesDialog);
  }


  public void userLoggedIn() {

      checkPrivileges();
  }


  private void checkPrivileges() {

    if (!_user.getPrivAllAccess()) {
        mnuProgramPositions.setEnabled(false);
        mnuCourses.setEnabled(false);

    } else {

        mnuProgramPositions.setEnabled(true);
        mnuCourses.setEnabled(true);
    }
  }


  
  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
  private void initComponents() {
    mainMenuBar = new javax.swing.JMenuBar();
    mnuProgram = new javax.swing.JMenu();
    mnuProgramAbout = new javax.swing.JMenuItem();
    mnuProgramExit = new javax.swing.JMenuItem();
    mnuPrint = new javax.swing.JMenu();
    deleteMenuItem1 = new javax.swing.JMenuItem();
    pnlRight = new javax.swing.JPanel();
    lblDateTime = new javax.swing.JLabel();
    notifications1 = new org.foment.gem.beans.Notifications();
    pnlLeft = new javax.swing.JPanel();
    pnlNavigator = new javax.swing.JPanel();
    pnlMenu = new javax.swing.JPanel();
    try {
      javax.swing.UIManager.setLookAndFeel(metalLAF);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    desktop = new javax.swing.JDesktopPane();
    try {
      javax.swing.UIManager.setLookAndFeel(mainLAF);
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    mnuProgram.setBackground(new java.awt.Color(255, 255, 255));
    mnuProgram.setText(i18n("Program"));
    mnuProgramAbout.setText(i18n("About..."));
    mnuProgramAbout.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        mnuProgramAboutActionPerformed(evt);
      }
    });

    mnuProgram.add(mnuProgramAbout);

    mnuProgramExit.setText(i18n("Exit"));
    mnuProgramExit.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        mnuProgramExitActionPerformed(evt);
      }
    });

    mnuProgram.add(mnuProgramExit);

    mainMenuBar.add(mnuProgram);

    mnuPrint.setBackground(new java.awt.Color(255, 255, 255));
    mnuPrint.setText(i18n("Print"));
    deleteMenuItem1.setText("Delete");
    mnuPrint.add(deleteMenuItem1);

    mainMenuBar.add(mnuPrint);

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Foment Group - Gem 1.o");
    setBackground(new java.awt.Color(255, 255, 255));
    setExtendedState(MAXIMIZED_BOTH);
    pnlRight.setLayout(new java.awt.BorderLayout());

    pnlRight.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 3, 0, 0, new java.awt.Color(153, 153, 153)));
    pnlRight.setMinimumSize(new java.awt.Dimension(200, 100));
    lblDateTime.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    lblDateTime.setText("Date");
    lblDateTime.setMaximumSize(new java.awt.Dimension(200, 25));
    lblDateTime.setMinimumSize(new java.awt.Dimension(200, 25));
    lblDateTime.setOpaque(true);
    lblDateTime.setPreferredSize(new java.awt.Dimension(200, 25));
    pnlRight.add(lblDateTime, java.awt.BorderLayout.NORTH);

    pnlRight.add(notifications1, java.awt.BorderLayout.CENTER);

    getContentPane().add(pnlRight, java.awt.BorderLayout.EAST);

    pnlLeft.setLayout(new java.awt.BorderLayout());

    pnlLeft.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 0, 3, new java.awt.Color(153, 153, 153)));
    pnlNavigator.setLayout(new java.awt.BorderLayout());

    pnlNavigator.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createMatteBorder(3, 0, 0, 0, new java.awt.Color(153, 153, 153)), javax.swing.BorderFactory.createEmptyBorder(6, 6, 6, 6)));
    pnlNavigator.setMaximumSize(new java.awt.Dimension(200, 2147483647));
    pnlNavigator.setMinimumSize(new java.awt.Dimension(200, 15));
    pnlNavigator.setPreferredSize(new java.awt.Dimension(200, 15));
    pnlLeft.add(pnlNavigator, java.awt.BorderLayout.CENTER);

    pnlMenu.setLayout(new java.awt.BorderLayout());

    pnlMenu.setMaximumSize(new java.awt.Dimension(200, 25));
    pnlMenu.setMinimumSize(new java.awt.Dimension(200, 25));
    pnlMenu.setPreferredSize(new java.awt.Dimension(200, 25));
    pnlLeft.add(pnlMenu, java.awt.BorderLayout.NORTH);

    getContentPane().add(pnlLeft, java.awt.BorderLayout.WEST);

    desktop.setBackground(new java.awt.Color(153, 153, 153));
    desktop.setOpaque(false);
    getContentPane().add(desktop, java.awt.BorderLayout.CENTER);

    pack();
  }// </editor-fold>//GEN-END:initComponents

  private void mnuProgramAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuProgramAboutActionPerformed
    aboutDialog.setVisible(true);
    //desktop.add(aboutDialog);
    aboutDialog.toFront();
    
    aboutDialog.setLocation(new java.awt.Point(
      (desktop.getSize().width - aboutDialog.getSize().width) / 2 ,
      (desktop.getSize().height - aboutDialog.getSize().height) / 2
    ));
    //desktop.add(aboutDialog);
    
  }//GEN-LAST:event_mnuProgramAboutActionPerformed

  private void mnuProgramPositionsActionPerformed(java.awt.event.ActionEvent evt) {

    positionsDialog.setVisible(true);
    positionsDialog.toFront();

    positionsDialog.setLocation(new java.awt.Point(
      (desktop.getSize().width - positionsDialog.getSize().width) / 2 ,
      (desktop.getSize().height - positionsDialog.getSize().height) / 2
    ));
  }

  private void mnuCoursesActionPerformed(java.awt.event.ActionEvent evt) {

    coursesDialog.setVisible(true);
    coursesDialog.toFront();

    coursesDialog.setLocation(new java.awt.Point(
      (desktop.getSize().width - coursesDialog.getSize().width) / 2 ,
      (desktop.getSize().height - coursesDialog.getSize().height) / 2
    ));
  }

  private void mnuPrintStatisticsActionPerformed(java.awt.event.ActionEvent evt) {

    printStatsDialog.showDialog();
    printStatsDialog.toFront();
    printStatsDialog.setSize(1000, 700);
    

    printStatsDialog.setLocation(new java.awt.Point(
      (desktop.getSize().width - printStatsDialog.getSize().width) / 2 ,
      (desktop.getSize().height - printStatsDialog.getSize().height) / 2
    ));
  }


  private void mnuProgramExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuProgramExitActionPerformed
    System.exit(0);
  }//GEN-LAST:event_mnuProgramExitActionPerformed
    
  public void desktopFrameDeactivated(javax.swing.JInternalFrame frame) {
    setTitle("Foment Group Gem 1.o");
    setNavigatorComponent(null);

    javax.swing.JInternalFrame activateFrame = null;
    boolean noneSelected = true;
    
    for (javax.swing.JInternalFrame currentFrame: desktop.getAllFrames()) {
      if (currentFrame.isVisible()) activateFrame = currentFrame;
      if (currentFrame.isSelected()) noneSelected = false;
    }
    
    if (noneSelected && activateFrame != null) {
      try {
        while (!_frames.isEmpty()) {
          _frames.removeLast();
          desktopFrameActivated(_frames.getLast());
          return;
        }
      } catch (Exception ex) {
        desktopFrameActivated(employeesDialog);
      }
    }
    
  }
  
  public void desktopFrameActivated(javax.swing.JInternalFrame frame) {
    while (_frames.remove(frame));
    _frames.addLast(frame);
    
    if (org.foment.gem.dialogs.GemInternalDialog.class.isInstance(frame)) {
      org.foment.gem.dialogs.GemInternalDialog gid = (org.foment.gem.dialogs.GemInternalDialog)frame;
      if (gid.getNavigatorComponent() != null)
        setNavigatorComponent(gid.getNavigatorComponent());
    }
    setTitle(frame.getTitle() + " - Foment Group Gem 1.o");
    frame.toFront();
    frame.requestFocus();
    try {
      frame.setSelected(true);
    } catch (PropertyVetoException ex) {
      ex.printStackTrace();
    }
  }
  
  private void setNavigatorComponent(java.awt.Component navigation) {
    pnlNavigator.removeAll();
    if (navigation != null)
      pnlNavigator.add(navigation);
    pnlNavigator.repaint();
  }

  public void checkIfRunning() {
    String lockPath = org.foment.joliage3.core.system.Paths.getApplicationHomePath("/lock/");
    (new java.io.File(lockPath)).mkdirs();
    
    try {
      java.io.File lock = new java.io.File(lockPath + "lock");
      if (lock.exists()) {
        if (org.foment.joliage3.newt.Question.showQuestion(
          i18n("Question"),
          i18n("It seams that there is already a Gem instance running. What do you want to do? Choose 'Continue' only if you are sure that there is no Gem instance running."),
          i18n("Continue starting"),
          i18n("Exit program")
        ) != org.foment.joliage3.newt.Question.STATUS_YES)
          System.exit(0);
      }
      lock.createNewFile();
      lock.deleteOnExit();
    } catch (java.io.IOException e) {
      Logger.log("joliage2", "org.foment.jewel3.integrator", Logger.ERROR, "Unable to make lock file", e);
    }   

  }
  
  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {

    System.setProperty("file.encoding", "UTF-8");

    ApplicationInformation.setName("Gem");
    ApplicationInformation.setKey("gem");
    ApplicationInformation.setVersion(1);
    ApplicationInformation.setSubversion(0);
    ApplicationInformation.setRevision(0);

    String commandsFilePath = org.foment.joliage3.core.system.Paths.getApplicationHomePath("/commands.sql");
    
    if ((new java.io.File(commandsFilePath)).exists()) {
      try {
        for(String command: org.foment.joliage3.core.string.StringIO.readFromFile(commandsFilePath).split(";\n")) {
            System.err.println(command);
            
            Connection  conn = Database.getConnection();
            conn.createStatement().executeUpdate(command);
            conn.close();
        }
      } catch (Exception ex) {
        ex.printStackTrace();
      }
      return ; 
    }
    
    try {
      /*String query1 = "UPDATE Employee SET EmployeeWorkingYearsModified = EmployeeJobDate WHERE EmployeeWorkingYearsModified is NULL;";
      Database.getConnection().createStatement().executeUpdate(query1);*/
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    
    try {
      /*String query2 = "UPDATE Employee SET EmployeeWorkingYears = EmployeeWorkingYears + 1, " +
        "EmployeeWorkingYearsModified = ADDDATE(EmployeeWorkingYearsModified, INTERVAL 1 YEAR) WHERE " +
        "ADDDATE(EmployeeWorkingYearsModified, INTERVAL 1 YEAR) < NOW();";
      Database.getConnection().createStatement().executeUpdate(query2); */
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    // Starting
    
    log("Gem", "org.foment.gem.Integrator", Logger.DEBUG, "Program Started", null);

    
    boolean antialias = false;
    boolean defaultlaf = false;
    
    java.util.Locale.setDefault(new java.util.Locale("sr"));
    
    for (String arg : args)
      if (arg.equals("--antialias"))
        antialias = true;
      else if (arg.equals("--defaultlaf"))
        defaultlaf = true;
    
    if (antialias)
      System.setProperty("swing.aatext","true");
    
    if (!defaultlaf)
    try {
      javax.swing.UIManager.setLookAndFeel("com.birosoft.liquid.LiquidLookAndFeel");
      com.birosoft.liquid.LiquidLookAndFeel.setStipples(false);
      com.birosoft.liquid.LiquidLookAndFeel.setLiquidDecorations(false, "mac");
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
        (new Integrator()).setVisible(true);
      }
    });
  }

  public void translationLoaded(String name) {
    if (name.equals("core")) {
      
      _splash.addState(i18n("Loading translations"));
      _splash.addState(i18n("Connecting to the DB"));
      _splash.addState(i18n("Loading the report system"));
      _splash.addState(i18n("Building User Interface"));
      _splash.addState(i18n("Almost there"));
      _splash.addState(i18n("Program is up and running"));
      splash_proceedToNextState();
    }
  }

  public void translationsInitialized() {

  }

  public void splash_endState() {
    ( new Thread() {
            @Override
      public void run() {
        for (;;) {
          lblDateTime.setText(
            java.text.DateFormat.getDateTimeInstance().format(new java.util.Date())
          );
          try {
            sleep(3000);
            _splash.setVisible(false);
            invalidate(); repaint();
            return;
          } catch (InterruptedException ex) {
            ex.printStackTrace();
          }
        }
      }
    }).start();
  }
  
  public void splash_proceedToNextState() {
    _splash.proceedToNextState();
    try {
      java.lang.Thread.sleep(0000);
    } catch (InterruptedException e) {
      // Nije vazno
    }
  }

  public void logEvent(String progID, String file, int type, String message, Exception exception) {
    String caption = null;
    String fullMessage = i18n(message);
    
    switch (type) {
      case Logger.ERROR:
        caption = i18n("Error");
        break;
      case Logger.FATAL_ERROR:
        caption = i18n("Fatal Error");
        break;
      case Logger.MESSAGE:
        caption = i18n("Message");
        break;
      case Logger.WARNING:
        caption = i18n("Warning");
        break;
    }
    
    if (exception != null)
      fullMessage += "\n\n" + i18n("Original Exception Information") + ":\n" + exception.getLocalizedMessage();
    
    if (caption != null)
      org.foment.joliage3.newt.Message.showMessage(caption, fullMessage, i18n("Close"));

    if (type == Logger.FATAL_ERROR) System.exit(0);
  }
  
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JMenuItem deleteMenuItem1;
  private javax.swing.JDesktopPane desktop;
  private javax.swing.JLabel lblDateTime;
  private javax.swing.JMenuBar mainMenuBar;
  private javax.swing.JMenu mnuPrint;
  private javax.swing.JMenu mnuProgram;
  private javax.swing.JMenuItem mnuProgramAbout;
  private javax.swing.JMenuItem mnuProgramExit;
  private org.foment.gem.beans.Notifications notifications1;
  private javax.swing.JPanel pnlLeft;
  private javax.swing.JPanel pnlMenu;
  private javax.swing.JPanel pnlNavigator;
  private javax.swing.JPanel pnlRight;
  // End of variables declaration//GEN-END:variables

  private org.foment.gem.dialogs.EmployeesDialog employeesDialog;
  private org.foment.gem.dialogs.AboutDialog aboutDialog;
  private org.foment.gem.dialogs.PositionsDialog positionsDialog;
  //private org.foment.gem.dialogs.StatisticsDialogFinal printStatsDialog;
  private org.foment.gem.statistic.StatisticsDialog printStatsDialog;
  private org.foment.gem.dialogs.CoursesDialog coursesDialog;

  private javax.swing.JMenuItem mnuProgramPositions;
  private javax.swing.JMenuItem mnuPrintStatistics;
  private javax.swing.JMenuItem mnuCourses;
  public static User _user = new User();

}
